from constants import ANIMALS, GUA_NAMES, LIU_QIN, LIU_QIN_NUM_60, REMAINDER_TO_SIX_MODE, REMINDER_TO_WX, WX, WXDiff, \
    YAO_WEI, ZHI, ZHI_TO_WX
from core.gua_params.handle_gua_params import _toCoinsNumLst
from core.StemBranchCalculator import StemBranchCalculator
from core.time.handle_time import get_time_info
from mapping.GuaModel import GuaModel
from mapping.numLst2idx import GuaConverter


def expandItem(item, context):
    '''
    从词典原有的键值对扩展出新的键值对
    :param item:
    :param context:
    :return:
    '''
    if item in ['inner', 'outer']:
        # expected:(3,1,2,3,1,1) -> inner:(112,212);outer(111,211)（312分解为112，212） -> inner:()
        # coinNumLst = context.get('coinNumLst', [1]*6)
        coinNumLst = context['coinNumLst']
        numLst_dct = {'outer': tuple(coinNumLst[:3]), 'inner': tuple(coinNumLst[3:])}
        return GuaConverter.to_nature_idx_max3(numLst_dct[item])
        # return [GuaConverter(li).get_nature_idx() for li in formatMax3toMax2(numLst_dct[item])]
    elif item == 'animals':
        # 说明：list,len6,索引从0到5分别是六爻到初爻
        sixMode = context['six_mode']
        return [ANIMALS[(sixMode + 10 - i) % 6] for i in range(6)]
    elif item == 'liuQin':
        # zhi 转 六亲
        return [LIU_QIN_NUM_60[context['wx']][num % 12] // 12 if num else None for num in context['zhi']]
    elif item == 'gan':
        return StemBranchCalculator(context['coinNumLst'], True).to_gan()
    elif item == 'zhi':
        return StemBranchCalculator(context['coinNumLst'], True).to_zhi()
        # return gua_info_list_calculate(context['gua'], context['biangua'],context['triggerLst'])
    elif item == 'wx' and context['gua'] is not None:
        # gua 转 wx
        return REMINDER_TO_WX[context['gua'] // 8]
    elif item == 'coinNumLst' and context['gua'] is not None:
        # gua,bian_gua 转 coinsNumLst
        return _toCoinsNumLst(context['gua'], context.get('biangua'))[0]
    elif item == 'gua' and context['gua_name'] in GUA_NAMES:
        return GUA_NAMES.index(context['gua_name'])
    elif item == 'biangua':
        return GUA_NAMES.index(context['bg_name']) if context['bg_name'] in GUA_NAMES else None
    elif item == 'triggerLst':
        # coinNumLst = context.get('coinNumLst', [1] * 6)
        return [1 if r in [3, 0] else 0 for r in context['coinNumLst']]
    elif item == 'six_mode' and context['dg'] is not None:
        # dg 转 six_mode
        return REMAINDER_TO_SIX_MODE[context['dg'] % 10]
    elif item in ['selfIdx', 'otherIdx']:
        return context['so_indices'][0 if item[0] == 's' else 1]
    elif item == 'so_indices':
        if (gua_idx := context['gua']) is None:
            gua_idx = GUA_NAMES.index(context['gua_name'])
        return GuaModel(gua_idx).get_self_other_pair()  # 爻位1-6
        # return search_self(gua_idx)  # 爻位1-6
    elif item == 'empty':
        return get_time_info(context)['empty']  # 爻位1-6

    else:
        raise KeyError(f'Dict could not expand this key:{item},current dict:{context}')


# 注意{}不能碰到 f-string
FLEXIBLE_PATTERN = f'^(世|应|间|空亡|{"|".join(ANIMALS)}|{"|".join(LIU_QIN)}|[年月日时][{"|".join(WXDiff)}]|' + \
                   '[年月日时][和差]\d{1,2})$'


# 完善神煞的逻辑
# 用于tensor的
def expand_flexible_mapping(item, context, gua_dict) -> str:
    if item in ['世', '应']:
        key = 'selfIdx' if item == '世' else 'otherIdx'
        return YAO_WEI[gua_dict[key]] + '爻'
    elif item == '间':
        so_min = min(gua_dict['selfIdx'], gua_dict['otherIdx'])
        return '(' + '|'.join([i + '爻' for i in YAO_WEI[so_min + 1:so_min + 3]]) + ')'
    elif item == '空亡':
        return '(' + ZHI[gua_dict['empty']] + '|' + ZHI[(gua_dict['empty'] + 1) % 12] + ')'
    elif item in ANIMALS:
        animal_idx = ANIMALS.index(item)
        line = (gua_dict['six_mode'] + 10 - animal_idx) % 6
        return YAO_WEI[line] + '爻'
    elif item in LIU_QIN:
        wx_gua = gua_dict['wx']
        lq_idx = LIU_QIN.index(item)
        return WX[(lq_idx + wx_gua) % 5]
    elif item[0] in ['年', '月', '日', '时']:
        _map = {'年': 'y', '月': 'm', '日': 'd', '时': 'h'}
        time_field = _map[item[0]]
        zhi_idx = gua_dict.get(time_field)
        if zhi_idx is None:
            return None
        if len(item) == 2 and item[1] in WXDiff:
            diff = WXDiff.index(item[1])
            return WX[(diff + ZHI_TO_WX[zhi_idx]) % 5]
        elif item[1] in ['和', '差'] and item[2:].isdigit():
            idx = int(item[2:])
            if item[1] == '和':
                return ZHI[(idx - zhi_idx) % 12]
            else:
                return ZHI[(idx + zhi_idx) % 12]
        else:
            raise ValueError(f'无法识别该词汇，请检查：{item}')
    else:
        raise ValueError(f'无法识别该词汇，请检查：{item}')


if __name__ == '__main__':
    import re

    expr = '月和3'
    pattern = '[年月日时][和差]\d{1,2}'
    match = re.match(FLEXIBLE_PATTERN, expr)
    # match = re.match(pattern, expr)
    print(match)
